package com.childmiles.gwt.client.ui;

import java.util.List;

import com.childmiles.gwt.client.AwardWinnerService;
import com.childmiles.gwt.client.AwardWinnerServiceAsync;
import com.childmiles.gwt.client.domain.AwardWinner;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.Cell;

public class MainPanel extends Composite {

    /**
     * Create a remote service proxy to talk to the server-side service.
     */
    private final AwardWinnerServiceAsync awardWinnerService = GWT.create(AwardWinnerService.class);

    private FlowPanel fullScreenContainer;
    
    private AwardWinner currentAwardWinner;

    public MainPanel() {
        //Container
        fullScreenContainer = new FlowPanel();
        fullScreenContainer.addStyleName("fullScreenContainer");
        
        //Header
        FlowPanel headerPanel = new FlowPanel();
        Image bannerImage = new Image("/images/banner.jpg");
        bannerImage.setTitle("Logout");
        bannerImage.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                Window.Location.reload(); //cheap logout :)
            }
        });
        headerPanel.add(bannerImage);
        fullScreenContainer.add(headerPanel);
        
        //Login
        fullScreenContainer.add(createLoginPanel());
        
        initWidget(fullScreenContainer);
    }

    //TODO take this method out I think
    private void createAndShowContentPanel() {
        FlowPanel contentPanel = new FlowPanel();
        contentPanel.addStyleName("wrapper");
        contentPanel.add(createAwardsPanel());
        setMainContent(contentPanel);
    }

    private Widget createLoginPanel() {
        FlowPanel loginPanel = new FlowPanel();
        Label welcome = new Label("Welcome!");
        welcome.addStyleName("title");
        loginPanel.add(welcome);
        loginPanel.add(new Label("What is your child's name?"));
        final TextBox awardWinnerNameTextBox = new TextBox();
        awardWinnerNameTextBox.addStyleName("horizontal");
        Button okButton = new Button("OK");
        okButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                if (!awardWinnerNameTextBox.getText().isEmpty()) {
                    loginAsAwardWinner(awardWinnerNameTextBox.getText());
                }
            }
        });
        awardWinnerNameTextBox.addKeyDownHandler(new KeyDownHandler() {
            public void onKeyDown(KeyDownEvent event) {
                if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
                    if (!awardWinnerNameTextBox.getText().isEmpty()) {
                        loginAsAwardWinner(awardWinnerNameTextBox.getText());
                    }
                }
            }
        });
        
        loginPanel.add(awardWinnerNameTextBox);
        loginPanel.add(okButton);
        
        //Statistics
        
        //Title
        Label rankingsLabel = new Label("Rankings");
        rankingsLabel.addStyleName("title");
        loginPanel.add(rankingsLabel);
        //Content
        FlexTable statisticsPanel = new FlexTable();
        createStatisticsPanel(statisticsPanel);
        loginPanel.add(statisticsPanel);
        
        //TODO is there any advantage to wrapping in a FormPanel?
        FormPanel loginForm = new FormPanel();
        loginForm.setWidget(loginPanel);
        
        //Set focus
        DeferredCommand.addCommand(new Command() {
            public void execute() {
                awardWinnerNameTextBox.setFocus(true);
            }
        });

        return loginForm;
    }

    private void createStatisticsPanel(final FlexTable container) {
//        TODO turn this into a table
//        container.add
        awardWinnerService.findAll(new AsyncCallback<List<AwardWinner>>() {
            public void onFailure(Throwable e) {
                throw new RuntimeException(e);
            }
            public void onSuccess(List<AwardWinner> awardWinners) {
                for (int i=0; i<awardWinners.size(); i++) {
                    final AwardWinner awardWinner = awardWinners.get(i);
                    //Header
                    Label nameLabel = new Label("Name");
                    nameLabel.setStyleName("tableHeader");
                    container.setWidget(0,0,nameLabel);
                    Label awardsLable = new Label("Awards");
                    awardsLable.setStyleName("tableHeader");
                    container.setWidget(0,1,awardsLable);

                    //Rows
                    Anchor awardWinnerNameLabel = new Anchor(awardWinner.getName());
                    awardWinnerNameLabel.addClickHandler(new ClickHandler() {
                        public void onClick(ClickEvent event) {
                            loginAsAwardWinner(awardWinner.getName());                        }
                    });
                    container.setWidget(i+1,0,awardWinnerNameLabel);
                    Label totalNumberAwardsLabel = new Label("" + 
                            awardWinner.getAwards().getTotalNumberOfAwards());
                    totalNumberAwardsLabel.addStyleName("totalNumberOfRewardsLabel");
                    container.setWidget(i+1,1,totalNumberAwardsLabel);
                }
            }
        });
    }

    /**
     * Find award winner and set it as currentAwardWinner
     * @param awardWinnerName
     */
    private void loginAsAwardWinner(final String awardWinnerName) {
        awardWinnerService.find(awardWinnerName,new AsyncCallback<AwardWinner>() {
            public void onFailure(Throwable caught) {
                throw new RuntimeException(caught);
            }
            public void onSuccess(AwardWinner result) {
                if (result == null) { //not found
                    currentAwardWinner = new AwardWinner(awardWinnerName);
                    createAndShowContentPanel();
                }
                else {
                    currentAwardWinner = result;
                    createAndShowContentPanel();
                }
            }
        });
    }

    private Widget createAwardsPanel() {
        FlowPanel awardsPanel = new FlowPanel();
        Label title = new Label("Awards For " + currentAwardWinner.getName());
        title.addStyleName("title");
        awardsPanel.add(title);
        
        final FlexTable awardsTable = new FlexTable();
        awardsTable.setSize("600px","500px");
        Image awardWinnerPhoto = new Image(currentAwardWinner.getPhotoUrl());
        awardWinnerPhoto.setTitle("Click for preferences");
        awardWinnerPhoto.addStyleName("awardWinnerImage");
        // 4 X 2 fixed grid
        awardsTable.setWidget(0,0,awardWinnerPhoto);
        awardsTable.setWidget(0,1,new AwardPanel(1, currentAwardWinner.getAwards().get(1)));
        awardsTable.setWidget(0,2,new AwardPanel(2, currentAwardWinner.getAwards().get(2)));
        awardsTable.setWidget(0,3,new AwardPanel(3, currentAwardWinner.getAwards().get(3)));
        awardsTable.setWidget(1,0,new AwardPanel(4, currentAwardWinner.getAwards().get(4)));
        awardsTable.setWidget(1,1,new AwardPanel(5, currentAwardWinner.getAwards().get(5)));
        awardsTable.setWidget(1,2,new AwardPanel(6, currentAwardWinner.getAwards().get(6)));
        awardsTable.setWidget(1,3,new AwardPanel(7, currentAwardWinner.getAwards().get(7)));
        
        awardsTable.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                Cell cellForEvent = awardsTable.getCellForEvent(event);
                if (cellForEvent == null) {
                    return;
                }
                int rowIndex = cellForEvent.getRowIndex();
                int colIndex = cellForEvent.getCellIndex();
                if (rowIndex == 0 && colIndex == 0) {
                    //for AwardWinnerImage go to settings screen
                    createAndShowSettingsPanel();
                    return;
                }
                AwardPanel awardPanel = (AwardPanel) awardsTable.getWidget(rowIndex,colIndex);
                EditAwardsDialog editAwardsDialog = new EditAwardsDialog(awardWinnerService, currentAwardWinner, awardPanel);
                editAwardsDialog.addStyleName("editAwardsDialog");
                editAwardsDialog.show();
            }
        });
        awardsPanel.add(awardsTable);
        return awardsPanel;
    }
    
    private void createAndShowSettingsPanel() {
        FlowPanel settingsPanel = new FlowPanel();
        //Title
        Label title = new Label("Settings");
        title.addStyleName("title");
        settingsPanel.add(title);
        
        //Back Button
        Button backToAwards = new Button("Back to Awards");
        backToAwards.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                setMainContent(createAwardsPanel());
            }
        });
        
        //Change Award Winner Image Form
        final TextBox newArwardWinnerPhotoURLTextBox = new TextBox();
        newArwardWinnerPhotoURLTextBox.addStyleName("horizontal");
        
        Button changeAwardWinnerPhotoButton = new Button("Change Award Winner Photo");
        changeAwardWinnerPhotoButton.addStyleName("horizontal");
        changeAwardWinnerPhotoButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                currentAwardWinner.setPhotoUrl(newArwardWinnerPhotoURLTextBox.getText());
                saveAwardWinner();
                createAndShowSettingsPanel(); //refresh
            }
        });
        
        Label currentAwardWinnerPhotoLabel = new Label("Current Award Winner Photo: ");
        
        Label newPhotoURLLabel = new Label("New Photo URL: ");
        newPhotoURLLabel.addStyleName("horizontal");
        
        FlowPanel changeAwardWinnerPhotoForm = new FlowPanel();
        
        changeAwardWinnerPhotoForm.add(newPhotoURLLabel);
        changeAwardWinnerPhotoForm.add(newArwardWinnerPhotoURLTextBox);
        changeAwardWinnerPhotoForm.add(changeAwardWinnerPhotoButton);
        
        settingsPanel.add(backToAwards);
        settingsPanel.add(currentAwardWinnerPhotoLabel);
        settingsPanel.add(new Image(currentAwardWinner.getPhotoUrl()));
        settingsPanel.add(changeAwardWinnerPhotoForm);

        
        setMainContent(settingsPanel);
    }

    // This method is duplicated in EditAwardsDialog :(
    protected void saveAwardWinner() {
        awardWinnerService.save(currentAwardWinner, new AsyncCallback() {
            public void onFailure(Throwable e) {
                throw new RuntimeException(e);
            }
            public void onSuccess(Object result) {
                // Good, do nothing
            }
        });
    }

    private void setMainContent(Widget content) {
        fullScreenContainer.remove(1);
        fullScreenContainer.add(content);
    }
    
}
